<?php


namespace services\buss;


use common\components\Service;
use common\helpers\CommonHelper;
use common\helpers\RedisHelper;
use common\models\base\Project;
use common\models\buss\Accounts;
use common\models\buss\Doctors;
use services\log\LogMemberOpService;
use services\member\MemberService;
use Yii;

class DoctorsService extends Service
{
    /**
     * 医生列表
     *
     * @param array $params
     * @param int $page
     * @param int $pageSize
     * @return array
     */
    public function doctorsList(array $params, int $page, int $pageSize): array
    {
        $query = Doctors::find()
            ->alias('d')
            ->select(['d.*', 'count(a.id) account_num'])
            ->leftJoin(Accounts::tableName() . ' a', 'a.doctor_id = d.id and a.status in '. '('.Accounts::STATUS_ENABLE.','. Accounts::STATUS_INVALID.')')
            ->where([
                'd.status' => [
                    Doctors::STATUS_ENABLE,
                    Doctors::STATUS_INVALID
                ],
                'd.project_id' => array_column(MemberService::getAllProjectListCondition(), 'value')
            ])->groupBy('d.id');
        // 搜索医生
        if (isset($params['keywords']) && $params['keywords']) {
            $query->andWhere(['d.name' => $params['keywords']]);
        }
        // 项目
        if (isset($params['project_id']) && $params['project_id']) {
            $query->andWhere(['d.project_id' => $params['project_id']]);
        }
        // 医生类型
        if (isset($params['type']) && $params['type']) {
            $query->andWhere(['d.type' => $params['type']]);
        }
        // 状态
        if (isset($params['status']) && is_numeric($params['status'])) {
            $query->andWhere(['d.status' => $params['status']]);
        }
        $orderBy = [];
        if (isset($params['order_column']) && $params['order_column']) {
            $sort = isset($params['order_sort']) && $params['order_sort'] == 'asc' ? SORT_ASC : SORT_DESC;
            switch ($params['order_column']) {
                case 'account_num':
                    $orderBy['account_num'] = $sort;
                    break;
                default :
                    break;
            }
        }
        $orderBy['d.status'] = SORT_DESC;
        $orderBy['d.id'] = SORT_DESC;

        $list = $this->getListPageRes($query, $page, $pageSize, $orderBy);
        foreach ($list['list'] as &$val) {
            $project = RedisHelper::getProject($val['project_id']);
            $val['project_name'] = $project && $project->status != Project::STATUS_DELETE ? $project->project_name : '';
            $val['status_name'] = Doctors::$statuss[$val['status']] ?? '';
            $val['pop_stars_name'] = Doctors::$popStars[$val['pop_stars']] ?? '';
            $val['type_name'] = Doctors::$types[$val['type']] ?? '';
        }
        return $list;
    }

    /**
     * 状态下拉筛选项
     * @return array[]
     */
    public static function getStatusCondition(): array
    {
        return [
            ['value' => Doctors::STATUS_ENABLE, 'label' => Doctors::$statuss[Doctors::STATUS_ENABLE]],
            ['value' => Doctors::STATUS_INVALID, 'label' => Doctors::$statuss[Doctors::STATUS_INVALID]],
        ];
    }

    /**
     * 医生类型下拉筛选项
     * @return array[]
     */
    public static function getTypeCondition(): array
    {
        return [
            ['value' => Doctors::TYPE_A, 'label' => Doctors::$types[Doctors::TYPE_A]],
            ['value' => Doctors::TYPE_B, 'label' => Doctors::$types[Doctors::TYPE_B]],
            ['value' => Doctors::TYPE_PRIVATE, 'label' => Doctors::$types[Doctors::TYPE_PRIVATE]],
        ];
    }

    /**
     * 获取正常的医生数据
     * @param int|array|null $orIds
     * @return array
     */
    public static function getEnableListByIds($orIds = null): array
    {
        $projectIds = array_column(MemberService::getProjectEditCondition(), 'value');
        $query = Doctors::find()
            ->select(['*'])
            ->where([
                'project_id' => $projectIds,
                'status' => Doctors::STATUS_ENABLE
            ]);
        if ($orIds) {
            $query->orWhere([
                'id' => $orIds,
                'status' => [Doctors::STATUS_ENABLE, Doctors::STATUS_INVALID],
//                'project_id' => $projectIds,
            ]);
        }
        return $query->orderBy(['id' => SORT_ASC])->all();
    }

    /**
     * 获取项目下正常的医生数据
     * @param int|array|null $orIds
     * @return array
     */
    public static function getProjectEnableListByIds(int $projectId, $orIds = null): array
    {
        $query = Doctors::find()
            ->select(['*'])
            ->where([
                'project_id' => $projectId,
                'status' => Doctors::STATUS_ENABLE
            ]);
        if ($orIds) {
            $query->orWhere([
                'id' => $orIds,
                'status' => [Doctors::STATUS_ENABLE, Doctors::STATUS_INVALID],
            ]);
        }
        return $query->orderBy(['id' => SORT_ASC])->all();
    }

    /**
     * 获取正常的医生数据
     * @param int|array|null $ids
     * @return array
     */
    public static function getNormalListByIds($ids = null): array
    {
        $query = Doctors::find()
            ->select(['*'])
            ->where([
                'project_id' => array_column(MemberService::getProjectListCondition(), 'value'),
                'status' => [Doctors::STATUS_INVALID, Doctors::STATUS_ENABLE]
            ]);
        if (!is_null($ids)) {
            $query->andWhere(['id' => $ids]);
        }
        return $query->orderBy(['id' => SORT_ASC])->all();
    }

    /**
     * 获取编辑筛选项
     * @param int|array|null $orIds
     * @return array
     */
    public static function getEditCondition($orIds = null): array
    {
        return CommonHelper::getListCondition(self::getEnableListByIds($orIds), ['value_column' => 'id', 'label_column' => 'name']);
    }

    /**
     * 获取指定项目编辑筛选项
     * @param int $projectId
     * @param int|array|null $orIds
     * @return array
     */
    public static function getProjectEditCondition(int $projectId, $orIds = null): array
    {
        return CommonHelper::getListCondition(self::getProjectEnableListByIds($projectId, $orIds), ['value_column' => 'id', 'label_column' => 'name']);
    }

    /**
     * 获取列表下拉筛选项
     * @return array
     */
    public static function getListCondition(): array
    {
        return CommonHelper::getListCondition(self::getNormalListByIds(), ['value_column' => 'id', 'label_column' => 'name']);
    }

    /**
     * 推广星级下拉筛选项
     * @return array[]
     */
    public static function getPopStarsCondition(): array
    {
        return [
            ['value' => Doctors::POP_STARS_ONE, 'label' => Doctors::$popStars[Doctors::POP_STARS_ONE]],
            ['value' => Doctors::POP_STARS_TWO, 'label' => Doctors::$popStars[Doctors::POP_STARS_TWO]],
            ['value' => Doctors::POP_STARS_THREE, 'label' => Doctors::$popStars[Doctors::POP_STARS_THREE]],
            ['value' => Doctors::POP_STARS_FOUR, 'label' => Doctors::$popStars[Doctors::POP_STARS_FOUR]],
            ['value' => Doctors::POP_STARS_FIVE, 'label' => Doctors::$popStars[Doctors::POP_STARS_FIVE]],
        ];
    }

    /**
     * 详情数据
     * @param int $id
     * @return array
     */
    public function getInfo(int $id): array
    {
        $data = [];
        // 内容信息
        $doctors = Doctors::findOne($id);
        if ($doctors) {
            $data = [
                'id' => $doctors->id,
                'project_id' => $doctors->project_id,
                'pop_stars' => $doctors->pop_stars,
                'hospital_name' => $doctors->hospital_name,
                'type' => $doctors->type,
                'status' => $doctors->status,
            ];
        }
        $condition = [
            'pop_stars_arr' => self::getPopStarsCondition(),
            'type_arr' => self::getTypeCondition(),
            'project_arr' => MemberService::getProjectEditCondition($data['project_id'] ?? null),
        ];

        if ($doctors) {
            if (in_array($data['project_id'], array_column($condition['project_arr'], 'value')) === false) {
                $data['project_id'] = 0;
            }
        }
        return array_merge($data, ['condition' => $condition]);
    }

    /**
     * 更新医生
     */
    public function updateDoctors(array $params): array
    {
        $doctors = new Doctors();
        // 是否为编辑，编辑判断排除当前ID
        $whereId = [];
        $scenario = 'create';
        $oldDoctors = null;
        if ($params['id']) {
            $whereId = ['!=', 'id', $params['id']];
            // 医生表
            $oldDoctors = self::getData($params['id']);
            $doctors = Doctors::findOne($params['id']);
            $scenario = 'edit';
        }
        // 判断名称是否存在
        $check = Doctors::find()
            ->select(['id'])
            ->where([
                'name' => $params['name'],
                'status' => [Doctors::STATUS_ENABLE, Doctors::STATUS_INVALID]
            ])
            ->andWhere($whereId)
            ->asArray()
            ->one();
        if ($check) {
            return CommonHelper::api(422, '医生已存在');
        }

        $transaction = Yii::$app->db->beginTransaction();
        try {
            // 医生编辑项目时，同步更新账号的项目
            if ($params['project_id'] != $doctors->project_id) {
                Accounts::updateAll([
                    'project_id' => $params['project_id'],
                    'operation_id' => Yii::$app->user->identity->member_id,
                    'operation_name' => Yii::$app->user->identity->member->realname,
                    'updated_at' => time()
                ], ['doctor_id' => $doctors->id]);
            }

            // 更新医生数据
            $params['pop_stars'] = $params['pop_stars'] ?? '';
            $doctors->name = $params['name'];
            $doctors->pop_stars = $params['pop_stars'] ?: '';
            $doctors->hospital_name = $params['hospital_name'];
            $doctors->type = $params['type'];
            $doctors->project_id = $params['project_id'];
            $doctors->status = $params['status'] ?? Doctors::STATUS_ENABLE;
            $doctors->operation_id = Yii::$app->user->identity->member_id;
            $doctors->operation_name = Yii::$app->user->identity->member->realname;
            $doctors->saveAndCheckResult();

            // 添加日志
            LogMemberOpService::createDoctorsLog($scenario, $doctors, $oldDoctors);
            $transaction->commit();
            return ['id' => $doctors->id];
        } catch (\Exception $e) {
            $transaction->rollBack();
            throw $e;
        }
    }

    /**
     * 医生数据
     * @param int $id
     * @return Doctors|null
     */
    public static function getData(int $id): ?Doctors
    {
        return Doctors::findOne($id);
    }

    /**
     * 医生删除
     */
    public function deleteDoctors(array $params): array
    {
        $transaction = Yii::$app->db->beginTransaction();
        try {
            // 更新设备状态为-1
            Doctors::updateAll([
                'status' => Doctors::STATUS_DELETE,
                'operation_id' => Yii::$app->user->identity->member_id,
                'operation_name' => Yii::$app->user->identity->member->realname,
                'updated_at' => time()
            ], ['id' => $params['id']]);
            // 添加日志
            LogMemberOpService::createDoctorsLog('delete', self::getData($params['id']));
            $transaction->commit();
            return ['id' => $params['id']];
        } catch (\Exception $e) {
            $transaction->rollBack();
            throw $e;
        }
    }

    /**
     * 根据项目统计医生数
     * @param $projectIds
     * @return array
     */
    public static function getStaticsNumByProject($projectIds): array
    {
        return Doctors::find()
            ->select(['project_id', 'COUNT(*) doctor_num'])
            ->where([
                'project_id' => $projectIds,
            ])
            ->andWhere(['!=', 'status', Doctors::STATUS_DELETE])
            ->indexBy('project_id')
            ->groupBy('project_id')
            ->asArray()
            ->all();
    }
}
